// STL
#include <tuple>                             // std::tie()
#include <utility>                           // std::pair<>, ::make_pair()
#include <vector>                            // std::vector<>

// this
#include "jScience/linalg/decomposition.hpp" // SVD()
#include "jScience/linalg/Matrix.hpp"        // Matrix<>


//
// DESC: Principal component analysis (PCA), on a data matrix X.
//
// -----
//
// INPUT:
//          Matrix<double>      X  :: data matrix
//
// OUTPUT:
//          Matrix<double>      VT :: eigenvectors of the matrix X^T*X (principal components)
//          std::vector<double> S  :: eigenvalues of the matrix X^T*X (proportional to the "variance" correlated with each eigenvector)
//
// =====
//
// NOTE: See:
//
//     http://wiki.statsxx.com/view/Principal_component_analysis
//
inline std::pair<
                 Matrix<double>,     // VT
                 std::vector<double> // S
                 > PCA(
                       const Matrix<double> &X
                       )
{
    Matrix<double>      VT;
    std::vector<double> S;

    Matrix<double> U;
    std::tie(
             U,
             S,
             VT
             ) = SVD(
                     X
                     );

    return std::make_pair(
                          VT,
                          S
                          );
}
